package com.dage;

import com.jfinal.kit.JavaKeyword;
import com.jfinal.kit.Kv;
import com.jfinal.kit.StrKit;
import com.jfinal.plugin.activerecord.dialect.MysqlDialect;
import com.jfinal.plugin.activerecord.generator.TableMeta;
import com.jfinal.template.Engine;
import io.jboot.codegen.CodeGenHelpler;
import io.jboot.exception.JbootException;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.nio.charset.StandardCharsets;
import java.util.List;

public class MyExcelModelGenerator {

	private final String projectPackage;
	private final String outputDir;
	private MyMetaBuilder metaBuilder;
	private final String template;
	protected Engine engine;
	protected JavaKeyword javaKeyword = JavaKeyword.me;

	public MyExcelModelGenerator(String projectPackage, String outputDir) {
		this.projectPackage = projectPackage;
		this.outputDir = outputDir;
		MyMetaBuilder metaBuilder = new MyMetaBuilder(CodeGenHelpler.getDatasource());
		metaBuilder.setDialect(new MysqlDialect());
		metaBuilder.setRemovedTableNamePrefixes("t_");
		metaBuilder.setGenerateRemarks(true);

		this.metaBuilder = metaBuilder;
		this.template = "excel_model_template.tp";
		initEngine();
	}

	protected void initEngine() {
		engine = new Engine();
		engine.setToClassPathSourceFactory();    // 从 class path 内读模板文件
		engine.addSharedMethod(new StrKit());
		engine.addSharedObject("javaKeyword", javaKeyword);
	}

	public void generate() {
		generate(metaBuilder.build(true));
	}

	public void generate(List<TableMeta> tableMetas) {
		System.out.println("Generate excel model ...");
		System.out.println("Excel Model Output Dir: " + outputDir);

		for (TableMeta tableMeta : tableMetas) {
			genBaseModelContent(tableMeta);
		}
		writeToFile(tableMetas);
	}

	protected void genBaseModelContent(TableMeta tableMeta) {
		Kv data = Kv.by("projectPackage", projectPackage);
		data.set("tableMeta", tableMeta);

		tableMeta.baseModelContent = engine.getTemplate(template).renderToString(data);
	}

	protected void writeToFile(List<TableMeta> tableMetas) {
		try {
			for (TableMeta tableMeta : tableMetas) {
				writeToFile(tableMeta);
			}
		} catch (IOException e) {
			throw new JbootException(e);
		}
	}

	/**
	 * base model 覆盖写入
	 */
	protected void writeToFile(TableMeta tableMeta) throws IOException {
		File dir = new File(outputDir);
		if (!dir.exists()) {
			dir.mkdirs();
		}

		String target = outputDir + File.separator + tableMeta.modelName + "Excel.java";
		try (OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream(target), StandardCharsets.UTF_8)) {
			osw.write(tableMeta.baseModelContent);
		}
	}

}
